package com.example.recordhelper.camera;

import com.example.recordhelper.common.FFmpegForwardAndRecordProcess;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author: zhouyuehan
 * @Date: 2024/10/25 17:01
 */
@Slf4j
@Component
public class RecordTaskExecutor {
    ConcurrentHashMap<Long, FFmpegDaemonThread> daemonMap = new ConcurrentHashMap<>();

    public void newTask(Long id, String input, String sourceId, String forwardUrl) {
        if (daemonMap.containsKey(id)) {
            log.info("录制任务[{}]已经正在执行", id);
            return;
        }
        FFmpegDaemonThread daemon = new FFmpegDaemonThread(daemonMap, id, input, sourceId, forwardUrl);
        daemon.start();
    }

    public void stopTask(Long id) {
        FFmpegDaemonThread t = daemonMap.get(id);
        if (t != null) {
            t.interrupt();
        }
    }

    @PreDestroy
    public void destroy() {
        log.info("开始销毁进程");
        for (Thread t : daemonMap.values()) {
            t.interrupt();
        }
        log.info("销毁进程结束");
    }

    class FFmpegDaemonThread extends Thread {

        boolean stopFlag = false;
        ConcurrentHashMap<Long, FFmpegDaemonThread> daemonMap;
        FFmpegForwardAndRecordProcess p;
        final Long id;
        final String input;
        final String sourceId;
        final String forwardUrl;

        public FFmpegDaemonThread(ConcurrentHashMap<Long, FFmpegDaemonThread> daemonMap, Long id, String input, String sourceId, String forwardUrl) {
            this.id = id;
            this.input = input;
            this.sourceId = sourceId;
            this.forwardUrl = forwardUrl;
            this.daemonMap = daemonMap;
            this.p = new FFmpegForwardAndRecordProcess(id, input, sourceId, forwardUrl);
            daemonMap.put(id, this);
        }

        @Override
        public void interrupt() {
            this.stopFlag = true;
            p.destroy();
            super.interrupt();
        }

        @Override
        public void run() {
            Integer exitCode = null;
            try {
                exitCode = p.waitFor();
            } catch (InterruptedException e) {
                log.error("[id={},pid={}] ffmpeg守护线程中断", p.getId(), p.getPid(), e);
            }
            daemonMap.remove(id);
            if (!stopFlag) {
                newTask(id, input, sourceId, forwardUrl);
                log.info("[id={},pid={}] ffmpeg进程异常结束，自动尝试重新拉起，返回状态：{}", p.getId(), p.getPid(), exitCode);
                return;
            }
            log.info("[id={},pid={}] ffmpeg进程结束，返回状态：{}", p.getId(), p.getPid(), exitCode);
        }
    }
}
